package com.beyond.parse.util;

import com.alibaba.druid.sql.SQLUtils;
import com.alibaba.druid.sql.ast.SQLStatement;
import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlSchemaStatVisitor;
import com.alibaba.druid.sql.dialect.oracle.visitor.OracleSchemaStatVisitor;
import com.alibaba.druid.sql.dialect.postgresql.visitor.PGSchemaStatVisitor;
import com.alibaba.druid.stat.TableStat;
import com.alibaba.druid.util.JdbcConstants;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class DruidUtil {

    public static Map<String, String> parseParameterMap(String sql, String dbType) {
        Map<String, String> parameterMap = new HashMap<String, String>();

        SQLStatement statement = getStatement(sql, dbType);
        List<TableStat.Condition> conditions = new ArrayList<TableStat.Condition>();
        if (JdbcConstants.ORACLE.equals(dbType)) {
            OracleSchemaStatVisitor visitor = new OracleSchemaStatVisitor();
            statement.accept(visitor);
            conditions = visitor.getConditions();
        } else if (JdbcConstants.MYSQL.equals(dbType)) {
            MySqlSchemaStatVisitor visitor = new MySqlSchemaStatVisitor();
            statement.accept(visitor);
            conditions = visitor.getConditions();
        } else if (JdbcConstants.POSTGRESQL.equals(dbType)) {
            PGSchemaStatVisitor visitor = new PGSchemaStatVisitor();
            statement.accept(visitor);
            conditions = visitor.getConditions();
        }

        if (!conditions.isEmpty()) {
            for (TableStat.Condition condition : conditions) {
                String flag = isContain(condition.getValues());
                if (flag != null) {
                    parameterMap.put(condition.getColumn().toString(), flag);
                }
            }
        }

        return parameterMap;
    }

    private static String isContain(List<Object> values) {
        for (Object value : values) {
            String tmp = value.toString();
            if (RegUtil.isRegContain(tmp, "(.*)&(.*)&(.*)")) {
                return RegUtil.regSubstring(tmp, "(?<=&)(.*)(?=&)").get(0);
            }
        }

        return null;
    }




    private static SQLStatement getStatement(String sql, String dbType) {
        List<SQLStatement> sqlStatements = SQLUtils.parseStatements(sql, dbType);
        if (!sqlStatements.isEmpty()) {
            return sqlStatements.get(0);
        }

        return null;
    }
}
